/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.muni.fi.hauntedhousesclient;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.JsonNode;
import cz.muni.fi.hauntedhouses.enums.Fear;
import cz.muni.fi.hauntedhouses.to.GhostTO;
import cz.muni.fi.hauntedhouses.to.SkillTO;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import net.sourceforge.stripes.action.ActionBean;
import net.sourceforge.stripes.action.ActionBeanContext;
import net.sourceforge.stripes.action.Before;
import net.sourceforge.stripes.action.DefaultHandler;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.RedirectResolution;
import net.sourceforge.stripes.action.Resolution;
import net.sourceforge.stripes.action.UrlBinding;
import net.sourceforge.stripes.controller.LifecycleStage;
import net.sourceforge.stripes.validation.Validate;
import net.sourceforge.stripes.validation.ValidateNestedProperties;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.client.RestTemplate;

/**
 *
 * @author Wendy
 */
@UrlBinding("/skills/{$event}/{skill.id}")
public class SkillActionBean implements ActionBean {

    static String STROJ = "localhost";
    static int PORT = 8080;
    static String WEBAPP = "pa165";
    static String URL = "http://" + STROJ + ":" + PORT + "/" + WEBAPP + "/rest/";
    private ActionBeanContext context;

    @Override
    public void setContext(ActionBeanContext context) {
        this.context = context;
    }

    @Override
    public ActionBeanContext getContext() {
        return context;
    }

    @DefaultHandler
    public Resolution all() {
        return new ForwardResolution("/showSkills.jsp");
    }
    @ValidateNestedProperties(value = {
        @Validate(on = {"add", "save"}, field = "name", required = true),
        @Validate(on = {"add", "save"}, field = "causesFear", required = true),
        @Validate(on = {"add", "save"}, field = "power", required = true, minvalue = 0, maxvalue = 100),
        @Validate(on = {"add", "save"}, field = "description", minlength = 0, maxlength = 50)
    })
    private SkillTO skill;

    public SkillTO getSkill() {
        return skill;
    }

    public void setSkill(SkillTO skill) {
        this.skill = skill;
    }

    public Resolution add() throws Exception{
        RestClient client = authenticate();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        HttpEntity<String> entity = new HttpEntity<String>(headers);
        String params = "skills?";
                              
        if (skill.getDescription() != null) {
            client.template().put(URL + "skills?name="+skill.getName()+ "&power=" + skill.getPower() + "&causesFear=" + skill.getCausesFear()+"&description=" + skill.getDescription(), entity);
        } else {
            client.template().put(URL + "skills?name="+skill.getName()+ "&power=" + skill.getPower() + "&causesFear=" + skill.getCausesFear(), entity);
        }
        return new RedirectResolution(this.getClass(), "all");
    }

    public List<SkillTO> getSkills() {
        List<SkillTO> list = new ArrayList<SkillTO>();
        RestClient client = authenticate();
        String url = URL + "skills";
        JsonNode jsonNode = client.template().getForObject(url, JsonNode.class);
        if (jsonNode != null) {
            List<JsonNode> nodes = jsonNode.findValues("skillTO");
            JsonNode innerNode = nodes.get(0);
            if (!innerNode.isArray()) {
                SkillTO s = new SkillTO();
                if (innerNode.get("name") != null) {
                    s.setName(innerNode.get("name").asText());
                }
                if (innerNode.get("description") != null) {
                    s.setDescription(innerNode.get("description").asText());
                }
                s.setCausesFear(Fear.valueOf(innerNode.get("causesFear").asText()));
                s.setId(innerNode.get("id").asLong());
                s.setPower(innerNode.get("power").asInt());
                list.add(s);
            } else {
                Iterator<JsonNode> iter = innerNode.elements();
                while (iter.hasNext()) {
                    JsonNode node = iter.next();
                    SkillTO s = new SkillTO();
                    if (node.get("name") != null) {
                        s.setName(node.get("name").toString());
                    }
                    if (node.get("description") != null) {
                        s.setDescription(node.get("description").toString());
                    }
                    s.setCausesFear(Fear.valueOf(node.get("causesFear").asText()));
                    s.setId(node.get("id").asLong());
                    if (node.get("power") != null) {
                        s.setPower(node.get("power").asInt());
                    }
                    list.add(s);
                }
            }

        }
        return list;
    }
    
    @Before(stages = LifecycleStage.BindingAndValidation, on = {"edit", "save"})
    public void loadSkillFromDatabase() {
        String ids = context.getRequest().getParameter("skill.id");
        if (ids != null) {
            RestClient client = authenticate();
            String url = URL+"skills/" + Long.parseLong(ids);
            JsonNode jsonNode = client.template().getForObject(url, JsonNode.class);
            SkillTO s = new SkillTO();
            if (jsonNode != null) {

                    if (jsonNode.get("id") != null) {
                        s.setId(jsonNode.get("id").asLong());
                    }
                    if (jsonNode.get("name") != null) {
                        s.setName(jsonNode.get("name").asText());
                    }
                    if (jsonNode.get("description") != null) {
                        s.setDescription(jsonNode.get("description").asText());
                    }
                    if (jsonNode.get("power") != null) {
                        s.setPower(jsonNode.get("power").asInt());
                    }
                    if (jsonNode.get("causesFear") != null) {
                        s.setCausesFear(Fear.valueOf(jsonNode.get("causesFear").asText()));
                    }
            }
            skill = s;
        }
    }
    
    public Resolution delete() {
        RestClient client = authenticate();
        client.template().delete(URL+"skills/" + skill.getId());       
        return new RedirectResolution(this.getClass(), "all");
    } 
    
     public Resolution edit() {
        return new ForwardResolution("/editSkill.jsp");
    }
 
    public Resolution save() {
        RestClient client = authenticate();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        HttpEntity<String> entity = new HttpEntity<String>(headers);
        if (skill.getDescription() == null) {
            client.template().postForLocation(URL+"skills/" + skill.getId() + "?name=" + skill.getName() + "&power=" + skill.getPower() + "&causesFear="+skill.getCausesFear(), entity);
        } else {
            client.template().postForLocation(URL+"skills/" + skill.getId() + "?name=" + skill.getName() + "&power=" + skill.getPower() + "&causesFear="+skill.getCausesFear() + "&description=" + skill.getDescription(), entity);
        }
        return new RedirectResolution(this.getClass(), "all");
    }
    
    public Resolution cancel() {
        return new RedirectResolution(this.getClass(), "all");
    }
    
    public RestClient authenticate() {
        RestClient client = new RestClient();
        
        client.setApplicationPath(WEBAPP);
        String url1 = client.login("rest", "rest");
        
        return client;
    }
}
